package com.jichangxiu.flow.server.core.entity.Bo;

import cn.hutool.core.util.ObjectUtil;
import com.jichangxiu.flow.server.core.entity.dto.Edge;
import com.jichangxiu.flow.server.core.entity.dto.Node;
import com.jichangxiu.flow.server.core.entity.dto.Text;
import com.jichangxiu.flow.server.core.enums.PropertyEnums;
import com.jichangxiu.flow.server.core.utils.BaseUtils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * NodeBo:
 *
 * @author Jcx
 * @create 2025-01-01 00:00:00
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class NodeBo implements Serializable, Cloneable {

    private static final long serialVersionUID = 1L;

    private String id;

    private String parentId;

    private String cycleParentId;

    private String type;

    private Integer x;

    private Integer y;

    private Map<String, Object> properties;

    private Text text;

    private List<String> children;

    private String code;

    private String category;

    private List<EdgeBo> sourceEdgeBoList;

    private List<EdgeBo> targetEdgeBoList;

    private List<NodeBo> childNodeBoList;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public static NodeBo initNodeBo(Node node, Map<String, List<Edge>> sourceIdByEdgeListToMap, Map<String, List<Edge>> targetIdByEdgeListToMap) {
        NodeBo nodeBo = new NodeBo();
        nodeBo.setId(node.getId());
        nodeBo.setType(node.getType());
        nodeBo.setX(node.getX());
        nodeBo.setY(node.getY());
        nodeBo.setProperties(node.getProperties());
        nodeBo.setText(node.getText());
        nodeBo.setChildren(node.getChildren());
        nodeBo.setCode(BaseUtils.getPropertyValue(nodeBo, PropertyEnums.code.name()));
        nodeBo.setCategory(BaseUtils.getPropertyValue(nodeBo, PropertyEnums.category.name()));
        List<Edge> sourceEdgeList = sourceIdByEdgeListToMap.get(nodeBo.getId());
        if (ObjectUtil.isNotEmpty(sourceEdgeList)) {
            nodeBo.setSourceEdgeBoList(sourceEdgeList.stream().map(EdgeBo::initEdgeBo).collect(Collectors.toList()));
        } else {
            nodeBo.setSourceEdgeBoList(new ArrayList<>());
        }
        List<Edge> targetEdgeList = targetIdByEdgeListToMap.get(nodeBo.getId());
        if (ObjectUtil.isNotEmpty(targetEdgeList)) {
            nodeBo.setTargetEdgeBoList(targetEdgeList.stream().map(EdgeBo::initEdgeBo).collect(Collectors.toList()));
        } else {
            nodeBo.setTargetEdgeBoList(new ArrayList<>());
        }
        return nodeBo;
    }

}
